﻿using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace XNA_TD
{
    public class RenderShadowMap : IRunable, IRTT
    {
        public static Vector3 lightDir = new Vector3(-1, -1, -1);
        public static Texture2D shadowMap;
        RenderTarget2D renderTarget;
        int shadowMapSize = 2048;
        public float depthBias = 0.002f;

        public RenderShadowMap()
            : base(Priority.Logic)
        {
            if (GameManager.isHiDef)
            {
                shadowMapSize *= 2;
                depthBias = 0.0015f;
            }
            lightDir.Normalize();
            shader.Parameters["DepthBias"].SetValue(depthBias);
            shader.Parameters["LightDir"].SetValue(lightDir);
            renderTarget = new RenderTarget2D(graphics.GraphicsDevice, shadowMapSize, shadowMapSize, false, SurfaceFormat.Single, DepthFormat.Depth24);
        }

        public void RTT()
        {
            var depthStencilState = graphics.GraphicsDevice.DepthStencilState;
            shadowMap = null;

            var terrainPos = new Vector3(kamera.position.X, 0, kamera.position.Z - 30);

            lightViewMatrix = Matrix.CreateLookAt(terrainPos - lightDir * 30, terrainPos, Vector3.Up);
            float aspect = graphics.GraphicsDevice.DisplayMode.AspectRatio;
            lightProjectionMatrix = Matrix.CreateOrthographic(
                75,
                35,
                5,
                52);

            shader.Parameters["LightViewProjection"].SetValue(lightViewMatrix * lightProjectionMatrix);

            graphics.GraphicsDevice.SetRenderTarget(renderTarget);
            graphics.GraphicsDevice.Clear(ClearOptions.Target | ClearOptions.DepthBuffer, Color.Black, 1.0f, 0);

            terrain.DrawShadow();
            foreach (var tower in gameManager.getRenderList(Priority.Tower))
            {
                var t = tower as GameObject;
                if (t != null)
                {
                    t.DrawShadow();
                }
            }
            foreach (var tower in gameManager.getRenderList(Priority.Einheit))
            {
                var t = tower as GameObject;
                if (t != null)
                {
                    t.DrawShadow();
                }
            }
            shadowMap = (Texture2D)renderTarget;
            graphics.GraphicsDevice.DepthStencilState = depthStencilState;
            graphics.GraphicsDevice.SetRenderTarget(null);
            shader.Parameters["ShadowMap"].SetValue(shadowMap);
        }

        public override void Load()
        {
        }

        public override void UnLoad()
        {
        }
    }
}
